<?php

/*
 * how to use operationContract:
 * in some serviceApp, if user what call operation in other serviceApp
 * caller should inialize instance of operationContract, then call doOperation
 * of operationContract
 * doOperation of operationContract will send operation request to queue of operation
 * then runner of serviceApp will get operation request when inialize instance
 * then run operation
 * when set destination of operation in operationContract, some requirement are needed
 * the rule of set destination of serviceApp is defined by developer of operationContract
 * for example, if set appContext = array(
 * 'service'=>'activeService' or specific service or all service
 * 'user'=>'currentUser' or specific user or all user
 * 'serviceApp'=>specific serviceApp
 * )
 */

/**
 * @tutorial 
 */
abstract class BOperationContract {

    const PermitType_AllowAccess = 'allowAccess';
    const SenderContext_Service = "sender_service";
    const SenderContext_User = 'sender_user';
    const SenderContext_ServiceApp = "sender_serviceApp";
    const ReceiverContext_Service = "receiver_service";
    const ReceiverContext_User = "receiver_user";
    const ReceiverContext_ServiceApp = "receiver_serviceApp";
    const OperationContext_Permit = "operation_permit";
    const Context_Value_ActiveServiceApp = 'activeServiceApp';
    const Context_Value_ActiveService = 'activeService';
    const Context_Value_CurrentUser = 'currentUser';
    const Context_Value_AllUser = "allUser";
    const Context_Value_AllService = "allService";
    const Context_Value_AllServiceApp = "allServiceApp";
    const Context_Value_Service_AllUser = "serviceAllUser";
    const Context_Value_RuntimeValue = "runtimeValue";
    const Context_Value_UserType_Expression = "userByExpression";
    const Context_Value_UserType_Circle = "userByCircle";
    const Context_Value_UserType_Role = "userByRole";
    const Context_Value_UserType_ServiceTeam = "serviceTeamUser";
    const Context_Value_FixedValue = "fixedValue";
    const Context_Value_UseRuntimePermit = "userRuntimePermit";
    const User_Scope_AllUser = -65101001;
    const Service_Scope_AllService = -65101002;
    const ServiceApp_Scope_AllServiceApp = -65101003;
    const UserType_Expression = -65101004;
    const UserType_Circle = -65101005;
    const UserType_Role = -65101010;
    const UserType_ServiceTeam = -65101006;
    const ServiceType_PersonalService = -65101007;

    //set default appContext is within current service
    /**
     * appContext is used to specify where to find sApp, default is within current
     * activeService
     * can also search serviceApp within all services of user, the appContext is 
     * currentUser
     * serviceApp can be point to specific service and specific user
     * then set appContext as condition of array such as
     * array('service'=>'serviceName','user'=>'userId',....)
     * @var type 
     */
    protected $operations = array();
    protected $apps = array();
    protected $sender = array();
    protected $receiver = array();
    protected $roleTemplate = null;
    protected $senderContext = array();
    protected $receiverContext = array();
    protected $operationRequests = array();
    protected $startTime = null;
    protected $checkSenderPermitResult = 'not-checked';
    protected $checkReceiverPermitResult = 'not-checked';
    protected $checkAutoProcessSenderPermitResult = 'not-checked';
    protected $isParsedOperationRequest = false;
    protected $operationName = null;

    function __construct($receiver = NULL, $sender = NULL) {
        //if Config changed, update contract      
        //$this->registerAppContext();
        //$this->registerOperations();
        //$this->sender = $sender;
        if ($this->roleTemplate == NULL)
            $this->roleTemplate = new BBasicRolesTemplate ();

        //set default sender value       
        /*
          $this->sender['userId'] = Blyn::app()->getCurrentUser()->getId();
          $this->sender['serviceId'] = Blyn::app()->getActiveService()->getId();
          $this->sender['serviceAppId'] = Blyn::app()->getActiveServiceApp()->getId();
         * 
         */

        //$this->registerOperationContext();
        //$this->registerOperations($receiver, $sender);
        //$this->parseOperationRequest($operation, $receiver, $sender);
    }

    public function assignRolesOfOperation($operationName, $target) {
        $allowedRoles = $this->getRolesOfOperation($operationName, self::PermitType_AllowAccess);
        $roleTemplate = $this->roleTemplate;
        $roleTemplate->assignRole($allowedRoles, $target);
    }

    /*
      public function addPermitsOfOperation($operationName, $resource) {
      if ($this->isAllowedSetPermits()) {
      $allowedRoles = $this->getRolesOfOperation($operationName, 'allowAccess');

      $roleTemplate = new BRoleTemplate();

      $roleTemplate->addPermit($allowedRoles, $resource);
      }
      }

      public function isAllowedSetPermits() {
      return FALSE;
      }
     * 
     */

    /*
      public function getOperation($operationName) {

      if (isset($this->operationMeta[$this-operationName])) {
      foreach ($this->apps as $app) {
      $op = $app->getOperation($operationName);

      if ($op instanceof BOperation)
      return $op;
      }
      }

      return FALSE;
      }
     * 
     */

    protected function parseOperationRequest($operation = null, $receiver = NULL, $sender = NULL) {
        
        $operationName = NULL;

        if (!$this->isParsedOperationRequest) {

            //add data of operation
            if (is_array($operation)) {
                $operationName = $operation['name'];

                if (!isset($this->operations[$operationName])) {
                    $this->operations[$operationName] = array();
                }

                $this->operations[$operationName] = array_merge($this->operations[$operationName], $operation);
            }

            if (is_string($operation)) {
                $operationName = $operation;
                $this->operations[$operationName]['name'] = $operationName;
            }

            if ($operationName != NULL)
                $this->operationName = $operationName;

            $this->registerOperationContext($operation, $receiver, $sender);

            if ($this->sender == NULL) {
                $this->sender['userId'] = Blyn::app()->getCurrentUser()->getId();
                $this->sender['serviceAppId'] = Blyn::app()->getActiveServiceApp()->getId();
                $this->sender['serviceId'] = Blyn::app()->getActiveService()->getId();
            }

            if (!isset($this->operations[$this->operationName]['senderContext'])) {
                $this->operations[$this->operationName]['senderContext'] = array();
            }
            if (!isset($this->operations[$this->operationName]['receiverContext'])) {
                $this->operations[$this->operationName]['receiverContext'] = array();
            }

            //by default, can sender is currentUser in activeServide and in activeServiceApp
            $this->operations[$this->operationName]['sender']['userId'] = $this->sender['userId'];
            $this->operations[$this->operationName]['sender']['serviceAppId'] = $this->sender['serviceAppId'];
            $this->operations[$this->operationName]['sender']['serviceId'] = $this->sender['serviceId'];

            if (isset($this->operations[$this->operationName]['senderContext'][self::SenderContext_User])) {
                if ($this->operations[$this->operationName]['senderContext'][self::SenderContext_User] == self::Context_Value_UserType_Circle) {
                    $this->operations[$this->operationName]['sender']['userId'] = self::UserType_Circle;
                    $this->operations[$this->operationName]['data']['sender_circleId'] =
                            $this->operations[$this->operationName]['senderContext']['data']['circleId'];
                }
            }

            /*
              if ($sender != NULL)
              $this->operations[$this->operationName]['sender'] = $sender;
             * 
             */
            /**
             * set receiver, by default, receiver's context in same as sender's
             * once specify receiver userid, do not set it to default value
             */
            if (isset($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_User])) {
                if ($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_User] == self::Context_Value_FixedValue)
                    $this->operations[$this->operationName]['receiver']['userId'] = $this->operations[$this->operationName]['receiverContext']['data']['userId'];

                //means can set sender_user in runtime
                if ($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_User] == self::Context_Value_RuntimeValue) {
                    if (isset($receiver['userId']))
                        $this->operations[$this->operationName]['receiver']['userId'] = $receiver['userId'];
                }

                if ($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_User] == self::Context_Value_UserType_ServiceTeam) {
                    if (isset($receiver['serviceTeam'])) {
                        $this->operations[$this->operationName]['receiver']['userId'] = self::UserType_ServiceTeam;
                        $this->operations[$this->operationName]['data']['receiver_serviceTeam'] = $receiver['serviceTeam'];
                    }
                }

                if ($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_User] == self::Context_Value_UserType_Circle) {
                    if (isset($receiver['circleId'])) {
                        $this->operations[$this->operationName]['receiver']['userId'] = self::UserType_Circle;
                        $this->operations[$this->operationName]['data']['receiver_circleId'] =
                                $this->operations[$this->operationName]['receiverContext']['data']['circleId'];
                    }
                }

                if ($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_User] == self::Context_Value_UserType_Role) {
                    if (isset($this->operations[$this->operationName]['receiverContext']['data']['roleId'])) {
                        $this->operations[$this->operationName]['receiver']['userId'] = self::UserType_Role;
                        $this->operations[$this->operationName]['data']['receiver_roleId'] =
                                $this->operations[$this->operationName]['receiverContext']['data']['roleId'];
                    }
                }


                //means send to all user
                if ($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_User] == self::Context_Value_AllUser) {
                    $this->operations[$this->operationName]['receiver']['userId'] = self::User_Scope_AllUser;
                }

                if ($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_User] == self::Context_Value_UserType_Expression) {
                    $this->operations[$this->operationName]['receiver']['userId'] = self::UserType_Expression;
                    $this->operations[$this->operationName]['data']['receiverByExpression'] = $receiver['receiverByExpression'];
                }
            }

            //means can set service in runtime
            if (isset($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_Service])) {

                if ($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_Service] == self::Context_Value_FixedValue)
                    $this->operations[$this->operationName]['receiver']['serviceId'] = $this->operations[$this->operationName]['receiverContext']['data']['serviceId'];

                if ($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_Service] == self::Context_Value_RuntimeValue) {
                    if (isset($receiver['serviceId']))
                        $this->operations[$this->operationName]['receiver']['serviceId'] = $receiver['serviceId'];
                }

                //means send to all service
                if ($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_Service] == self::Context_Value_AllService) {
                    $this->operations[$this->operationName]['receiver']['serviceId'] = self::Service_Scope_AllService;
                }
            }

            //means can set serviceApp in runtime
            if (isset($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_ServiceApp])) {

                if ($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_ServiceApp] == self::Context_Value_FixedValue)
                    $this->operations[$this->operationName]['receiver']['serviceAppId'] = $this->operations[$this->operationName]['receiverContext']['data']['serviceAppId'];

                if ($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_ServiceApp] == self::Context_Value_RuntimeValue) {
                    if (isset($receiver['serviceAppId']))
                        $this->operations[$this->operationName]['receiver']['serviceAppId'] = $receiver['serviceAppId'];
                }

                //means send to all serviceApp
                if ($this->operations[$this->operationName]['receiverContext'][self::ReceiverContext_ServiceApp] == self::Context_Value_AllServiceApp) {
                    $this->operations[$this->operationName]['receiver']['serviceAppId'] = self::ServiceApp_Scope_AllServiceApp;
                }
            }

            $this->isParsedOperationRequest = TRUE;
        }
    }

    /**
     * this function only list operation in queue of ServiceApp pending operation
     * list,
     * once serviceApp is active, it will execute operation in list
     * @param type $operationName
     * @param type $data 
     */
    public function sendOperationRequest($operation, $receiver = NULL, $sender = NULL) {

        $this->parseOperationRequest($operation, $receiver, $sender);        

        $this->startTime = time();

        $receiver = $this->operations[$this->operationName]['receiver'];
        $sender = $this->operations[$this->operationName]['sender'];
        $operation = $this->operations[$this->operationName];

        if ($this->checkReceiverPermit($operation, $receiver, $sender)) {
            $requestId = $this->addOperationRequestToStore($operation, array('status' => 'pending',
                'startTime' => $this->startTime, 'aliveLength' => 7 * 24 * 60 * 60)); //alive of request is one week)

            if ($this->checkAutoProcessSenderPermit($operation, $receiver, $sender)) {
                $this->autoProcessRequest($requestId, $operation, $receiver, $sender);
            }

            return TRUE;
        }

        return FALSE;

        /*
          if ($this->checkAccess($this->operations[$operation], $this->operations[$operation]['sender'], $this->operations[$operation]['receiver'])) {
          if ($this->operations[$operation]['receiver'] != NULL) {
          Blyn::app()->getAppDb()->addOperationRequest(array(
          'receiver' => $this->operations[$operation]['receiver'],
          'sender' => $this->operations[$operation]['sender'],
          'operation' => array('name' => $operation),
          'status' => array('status' => 'pending', 'startTime' => time(), 'aliveLength' => 7 * 24 * 60 * 60), //alive of request is one week
          'data' => $this->operations[$operation]['data']
          ));
          }
          }
         * 
         */
    }

    /**
     * format of operationMeta:
     * array('operation'=>array('receiver'=>array('receiver_id'=>'','receiver_serviceId'=>'','receiver_serviceAppId'=>'','receiver_context'=>'')
     *          'sender'=>'...',     *         
     *          'status'=>array('status'=>'pending',....),
     *          'data'=>array('senderByExpression'=>....))
     *      'operation2'=>array(....)
     * @param type $operationMeta
     */
    protected function registerOperations($receiver = NULL, $sender = NULL) {
        //$currentServiceApp = Blyn::app()->getActiveServiceApp();
        //$appOperations = $currentServiceApp->getConfigManager()->getConfig('appOperations');
        //$this->operations = $appOperations;
        //$this->registerOperationContext($receiver, $sender);
        //foreach ($this->operations as $name => $operationData) {
        //$this->parseOperationRequest($name, $receiver, $sender);
        //}
    }

    //this function is used to define rules to parse receiver and sender request base on receiver and sender input
    protected abstract function registerOperationContext($operation = NULL, $receiver = NULL, $sender = NULL);

    protected function getRolesOfOperation($operation, $permitType) {
        foreach ($this->operations as $name => $opData) {
            if ($name == $operation)
                return $opData[$permitType];
        }
        return FALSE;
    }

    protected function searchUser($condition) {

        $email = isset($condition['email']) ? $condition['email'] : NULL;

        if ($email != NULL) {
            return Blyn::app()->getAppDb()->getUserIdByLoginId($email);
        }

        return FALSE;
    }

    protected function searchService($condition) {

        $serviceName = isset($condition['serviceName']) ? $condition['serviceName'] : NULL;
        $serviceType = isset($condition['serviceType']) ? $condition['serviceType'] : BService::NORMALSERVICETYPE;
        $serviceCategory = isset($condition['serviceCategory']) ? $condition['serviceCategory'] : NULL;

        if ($serviceName != NULL) {
            return Blyn::app()->getAppDb()->searchService($serviceName, $serviceType, $serviceCategory);
        }

        return FALSE;
    }

    /**
     * 
     * @param type $condition, it contain classname of serviceApp
     * @return boolean
     */
    protected function searchServiceApp($condition) {

        //$appName = isset($condition['appName'])?$condition['appName']:NULL;
        $className = isset($condition['className']) ? $condition['className'] : $condition['appName'];

        $db = Blyn::app()->getActiveServiceApp()->getDbAdapter();

        if ($className != NULL)
            return $db->getServiceAppId($className);

        return FALSE;
    }

    protected function setRoleTemplate($roleTemplate = NULL) {
        if ($roleTemplate != NULL)
            $this->roleTemplate = $roleTemplate;
    }

    protected function getUserRoles($userId = null, $serviceId = null, $serviceAppId = NULL) {
        if ($userId == NULL)
            $userId = Blyn::app()->getCurrentUser()->getId();
        if ($serviceId == NULL)
            $serviceId = Blyn::app()->getActiveService()->getId();
        if ($serviceAppId == NULL)
            $serviceAppId = Blyn::app()->getActiveServiceApp()->getId();

        return Blyn::app()->getActiveServiceApp()->getAuthManager()->getUserRoles($userId, $serviceId, $serviceAppId);
    }

    /**
     * 
     * @param type $operation
     * @param mixed $sendPermit, can be array or string of role ist, if different sendpermit, maybe should override this function
     * @param array $sender
     * @return boolean
     * sometime, need to override this function if check of sender permit is different
     */
    protected function checkPermit($permits = array(), $visitor = array()) {

        $currentUserId = Blyn::app()->getCurrentUser()->getId();
        $visitor_serviceId = Blyn::app()->getActiveService()->getId();
        $visitor_serviceAppId = Blyn::app()->getActiveServiceApp()->getId();

        $visitor_userId = $currentUserId;

        if (isset($visitor['userId']))
            $visitor_userId = $visitor['userId'];

        if (isset($visitor['serviceId']))
            $visitor_serviceId = $visitor['serviceId'];

        if (isset($visitor['serviceAppId']))
            $visitor_serviceAppId = $visitor['serviceAppId'];

        $roleManager = Blyn::app()->getActiveServiceApp()->getAuthManager();

        //if login_member_role is in permit of visitor, means all user can send
        // request
        if (in_array(BBasicRolesTemplate::LOGIN_MEMBER_ROLE, $permits))
            return TRUE;

        $db = Blyn::app()->getActiveServiceApp()->getDbAdapter();

        if ($visitor_userId != self::UserType_Circle && $visitor_userId != self::UserType_Role)
            $userRoles = $this->getUserRoles($visitor_userId, $visitor_serviceId, $visitor_serviceAppId);

        //if visitor is circle, check access roles of visitor
        if (isset($visitor['circleId'])) {
            $circleId = $visitor['circleId'];

            if (!$roleManager->isMemberOfCircle($currentUserId, $circleId))
                return FALSE;

            $userRoles = $roleManager->getCircleRoles($circleId, $visitor_serviceAppId, $$visitor_serviceId);
        }

        $roleIdArray = array_keys($userRoles);

        //if all role of visitor cirles can match role of visitorPermit, return true
        foreach ($permits as $roleName) {
            $roleId = $roleManager->getRoleId($roleName, $visitor_serviceAppId);
            if (in_array($roleId, $roleIdArray))
                return true;
        }
        // }

        return FALSE;
    }

    protected function checkReceiverPermit($operation, $receiver = array(), $sender = array()) {

        $this->parseOperationRequest($operation, $receiver, $sender);

        if ($this->checkReceiverPermitResult == 'not-checked') {

            $receiverPermits = $this->getOperationPermits($operation['name'], 'receiverPermit', $receiver);

            //if not set receiverPermits, set as true by default
            if (!$receiverPermits)
                return TRUE;

            $permits = array_keys($receiverPermits);

            $this->checkReceiverPermitResult = $this->checkPermit($permits, $receiver);
        }

        return $this->checkReceiverPermitResult;
    }

    protected function checkSenderPermit($operation, $sender = array(), $receiver = array()) {

        $this->parseOperationRequest($operation, $receiver, $sender);

        if (is_string($operation)) {
            $name = $operation;
            $operation = array();
            $operation['name'] = $name;
        }

        if ($receiver == NULL) {
            $receiver = $this->operations[$operation['name']]['receiver'];
        }

        if ($this->checkSenderPermitResult == 'not-checked') {

            $senderPermits = $this->getOperationPermits($operation['name'], 'senderPermit', $receiver);

            //if not set receiverPermits, set as true by default
            if (!$senderPermits)
                return TRUE;

            $permits = array_keys($senderPermits);

            $this->checkSenderPermitResult = $this->checkPermit($permits, $sender);
        }

        return $this->checkSenderPermitResult;
    }

    protected function checkAutoProcessSenderPermit($operation, $receiver = array(), $sender = array()) {

        $this->parseOperationRequest($operation, $receiver, $sender);

        if ($this->checkAutoProcessSenderPermitResult == 'not-checked') {

            $senderPermits = $this->getOperationPermits($operation['name'], 'autoProcessSenderPermit', $receiver);

            //if not set receiverPermits, set as false by default
            if (!$senderPermits)
                return FALSE;

            $permits = array_keys($senderPermits);

            $this->checkAutoProcessSenderPermitResult = $this->checkPermit($permits, $sender);
        }

        return $this->checkAutoSenderPermitResult;
    }

    protected function autoProcessRequest($requestId, $operation = array(), $receiver = array(), $sender = array()) {
        return FALSE;
    }

    public function getOperationPermits($operation = array(), $permitName = null, $receiver = array(), $sender = array()) {

        $this->parseOperationRequest($operation, $receiver, $sender);

        if ($receiver == NULL) {
            $receiver = $this->operations[$this->operationName]['receiver'];
        }

        if (!isset($receiver['serviceAppId']) || $receiver['serviceAppId'] == NULL)
            return FALSE;

        $receiverApp = BServiceApp::getInstanceById($receiver['serviceAppId']);

        $authManager = $receiverApp->getAuthManager();

        $serviceId = isset($receiver['serviceId']) ? $receiver['serviceId'] : NULL;

        $permits = $authManager->getOperationPermits($this->operationName, $serviceId);

        if (isset($permits[$permitName]))
            return $permits[$permitName];

        return FALSE;
    }

    //get current user's operation requests
    public function getOperationRequests($operationName = NULL, $userList = null, $serviceList = NULL, $serviceAppList = NULL, $status = NULL, $timeLength = NULL) {

        $this->parseOperationRequest($operationName);       

        if ($this->operationRequests == NULL) {

            if ($status == NULL)
                $status = BOperationRequest::Status_Pending;

            //by default, set time length as one week
            if ($timeLength == NULL)
                $timeLength = 7 * 26 * 60 * 60;

            if ($userList == NULL)
                $userList = array();

            if ($serviceList == NULL)
                $serviceList = array();

            if ($serviceAppList == NULL)
                $serviceAppList = array();

            //add current user and all user to to userList
            array_push($userList, array('userId' => Blyn::app()->getCurrentUser()->getId()));
            array_push($userList, array('userId' => BOperationContract::User_Scope_AllUser));

            //add user's circle into userList
            if (Blyn::app()->getActiveService() != NULL) {
                $serviceId = Blyn::app()->getActiveService()->getId();
                $userId = Blyn::app()->getCurrentUser()->getId();
                $circles = Blyn::app()->getActiveServiceApp()->getAuthManager()->getUserCircles(Blyn::app()->getActiveService()->getId(), Blyn::app()->getCurrentUser()->getId());

                foreach ($circles as $circle) {
                    array_push($userList, array('circleId' => $circle->getId()));
                }

                //add user's current role into userList
                $roles = Blyn::app()->getActiveServiceApp()->getAuthManager()->getUserRoles($userId, $serviceId);

                foreach ($roles as $role) {
                    array_push($userList, array('roleId' => $role->getId()));
                }
            }

            //add current service and all service to servicelist
            if (Blyn::app()->getActiveService() != NULL) {
                $service = Blyn::app()->getActiveService();
                array_push($serviceList, array('serviceId' => Blyn::app()->getActiveService()->getId()));
                array_push($serviceList, array('serviceId' => BOperationContract::Service_Scope_AllService));

                //add personal service into list if send request to personalService
                if ($service->getServiceType() == BService::PERSONALSERVICETYPE)
                    array_push($serviceList, array('serviceId' => BOperationContract::ServiceType_PersonalService));
            }

            //add current serviceApp and all serviceApp to serviceApplist
            array_push($serviceAppList, array('serviceAppId' => Blyn::app()->getActiveServiceApp()->getId()));
            array_push($serviceAppList, array('serviceAppId' => BOperationContract::ServiceApp_Scope_AllServiceApp));

            $opRequests = $this->getStoredOperationRequest($this->operationName, $userList, $serviceList, $serviceAppList, array('status' => $status, 'timeLength' => $timeLength));

            $this->operationRequests = $opRequests;
        }

        return $this->operationRequests;
    }

    //this function use to update data of operation
    public function updateOperationRequestData($requestId, $data = array()) {

        $operationRequest = BMOperationRequest::model()->findByPk($requestId);

        if (isset($data['status'])) {
            $operationRequest->status = $data['status'];
            $operationRequest->save();
        }
    }

    protected function addOperationRequestToStore($operation, $status) {

        if ($operation['receiver'] != NULL) {
            if ($this->checkSenderPermit($operation['name'], $operation['sender'], $operation['receiver'])) {
                return Blyn::app()->getAppDb()->addOperationRequest(array(
                            'receiver' => $operation['receiver'],
                            'sender' => $operation['sender'],
                            'operation' => array('name' => $operation['name']),
                            //     'status' => array('status' => 'pending', 'startTime' => time(), 'aliveLength' => 7 * 24 * 60 * 60), //alive of request is one week
                            'status' => $status,
                            'data' => $operation['data']
                        ));
            }
        }

        return FALSE;
    }

    public function getOperationRequestIdByStartTime($operationName, $startTime) {
        return Blyn::app()->getAppDb()->getOperationRequestIdByStartTime($operationName, $startTime);
    }

    protected function getStoredOperationRequest($operationName, $userList, $serviceList, $serviceAppList, $status) {

        $db = Blyn::app()->getActiveServiceApp()->getDbAdapter();

        $opRequests = array();

        foreach ($userList as $userData) {
            foreach ($serviceList as $serviceData) {
                foreach ($serviceAppList as $appData) {
                    $oRequests = $db->getOperationRequests($operationName, $userData, $serviceData, $appData, $status);
                    foreach ($oRequests as $oRequest) {
                        $opRequests[$oRequest->id] = $oRequest;
                    }
                    //$opRequests = array_merge($opRequests, $db->getOperationRequests($userData, $serviceData, $appData, array('status' => $status, 'timeLength' => $timeLength)));
                }
            }
        }

        return $opRequests;
    }

}

?>
